<!-- model的公共组件：增删改查; -->
<template>
  <starGenView :title="title">
    <cfg-table v-if="!!this.collectionObject"
      ref="table"
      :columns="columns"
      :data="collectionObject.records"
      :loading="loading"
      :config="tableConfig"
      :pageSizeOpts="pageSizeOpts"
      :pageNavigation="pageNavigation"
      :queryFormItem="queryFormItem"
      :collapseFormItem="collapseFormItem"
      :actionButtons="actionButtonsCalc"
      :additionalAction="additionalAction"
      :searchHistory="searchHistory"
      @loadPage="loadPage"
      @handleClick="(row, index) => $emit('handleClick', row, index)"
      @handleDbClick="(row, index) => $emit('handleDbClick', row, index)"
      @handleSelect="(selection, row) => $emit('handleSelect', selection, row)"
      @handleSelectCancel="(selection, row) => $emit('handleSelectCancel', selection, row)"
      @handleCreate="handleCreate"
      @handleDetail="handleDetail"
      @handleEdit="handleEdit"
      @handleDelete="handleDelete"
      @handleDeleteMultiple="handleDeleteMultiple"
      @handleSearch="handleSearch"
      @handleReset="handleReset"
    />
    <cfgCrudAddModal v-show="modelDrawer.status==='new'"
      v-bind="modalConfig"
      :classObject="classObject"
      :collectionObject="collectionObject"
      :drawer="modelDrawer"
      :fields="modalFormItem"
      @submit="handleNewAddSubmit"
    />
    <cfgCrudModal v-show="modelDrawer.status!=='new'"
      v-bind="modalConfig"
      :modalTitle="modalTitle"
      :classObject="classObject"
      :collectionObject="collectionObject"
      :drawer="modelDrawer"
      :fields="modalFormItem"
      @submit="handleEditSubmit"
    />
    <cfgModalHier
      v-bind="modalConfig"
      :modalTitle="modalTitle"
      :classObject="classObject"
      :collectionObject="collectionObject"
      :drawer="registerDrawer"
      @submit="handleHierEditSubmit"
      @nodeSelect="data => $emit('nodeSelect', data)"
    />
  </starGenView>
</template>

<script>
import cfgCrudModal from 'public/components/configComp/basic/cfgCrud/cfgCrud-modal'
import cfgCrudAddModal from 'public/components/configComp/basic/cfgCrud/cfgCrud-AddModal'
import util from '../util'

export default {
  name: 'modelDesign_model',
  components: { cfgCrudAddModal, cfgCrudModal },
  data() {
    let data = this.tools.lodash.merge({
      modelName: `${this.prefix}Model`,
      modelFilter: '',
      classObject: null,
      collectionObject: null,
      loading: false,
      modalNeedQuery: true,
      pageSizeOpts: [10, 30, 50, 100],
      pageNavigation: { total: 0, pageSize: 30, pageNumber: 1 },
      modalConfig: {
          hasFeatures: true,
          labelWidth: 90,
      },
      modelDrawer: {
        status: 'new',
        show: false
      },
      registerDrawer: {
        show: false
      },
      tableConfig: {
        search: true,
        addButton: true,
        actionEdit: true,        // 显示编辑按钮, 默认为true
        actionDetail: true,      // 显示查看按钮, 默认为true
        actionDelete: true,      // 显示删除按钮, 默认为true
        // actionCopy: true,
        batchDeleteButton: true, // 显示批量删除按钮
        downloadIcon: true,
        uploadIcon: true,
        uploadUrl: '/',
        tableSizeIcon: true,
        fullscreenIcon: true,
        refreshIcon: true,
        columnSettingIcon: true,
        action: true,
        actionOption: { // action的配置
          // width: 260,
          // fixed: 'right',
          // align: 'center',
        },
        actionButtons: [
          // {
          //   title: { 'zh-CN': '注册', 'en-US': 'register' }, color: 'green',
          //   eventName: 'actionRegister'
          // }
        ],   // action追加的button
        additionalAction: {  // 附加操作的配置，以及button列表
          show: true,
          width: 100,
          buttons: [
            {
              title: { 'zh-CN': '注册', 'en-US': 'register' }, color: 'green',
              eventName: 'actionRegister'
            }
          ]
        }
      },
      searchHistory: this.prefix,
    }, this.config)
    return data
  },
  methods:{
    async loadPage(pageNavigation, filter = {}) {
      filter = this.isReset ? filter : {...filter, ...this.searchData}
      if (this.isPointer) {
        delete filter.nodeId
      }

      let condition=this.collectionObject.util.getFilter(filter, 'like')
      
      if (this.modelFilter) {
        condition += (condition ? ' and ' : '') + this.modelFilter
      }
      this.loading = true;
      let flag = await this.collectionObject.queryInfoByPage(pageNavigation.pageNumber, pageNavigation.pageSize, condition)

      if (flag) {
        this.pageNavigation.total = this.collectionObject.total;
        // this.dataChange('query')
        this.loading = false;
      } else {
        this.loading = false;
      }
    },
    handleSearch(filter) {
      this.pageNavigation.pageNumber = 1;
      this.loadPage(this.pageNavigation, filter)
    },
    handleReset() {
      this.isReset = true
      this.pageNavigation.pageNumber = 1;
      this.loadPage(this.pageNavigation)
    },
    async actionRegister(row, index) {
      let filter = { type: row.type, className: row.className }
      this.loading = true;
      this.registerDrawer.status = 'edit'

      if (!this.modalNeedQuery) {
        this.classObject.setRecord(row)
        this.registerDrawer.show = true
        this.loading = false
      }
      else if (await this.getRecord(filter)) {
        this.registerDrawer.show = true
        this.loading = false
      } else {
        this.loading = false
      }
    },
    async getRecord(filter) {
      let flag = await this.classObject.query(this.collectionObject.util.getFilter(filter))
      return flag
    },
    async deleteRecord(classNames) {
      this.loading = true;
      let flag= await this.collectionObject.deleteByClassNames(classNames)

      this.clearTableSelection(flag)
      this.dataChange('delete')
      this.loading = false;
      return flag
    },
    async deleteRecordById(ids) {
      this.loading = true;
      let flag= await this.collectionObject.deleteByIds(ids)

      this.clearTableSelection(flag)
      this.dataChange('delete')
      this.loading = false;
      return flag
    },
    async handleNewAddSubmit() {
      this.loading = true;
      if (await this.classObject.add()) {
        this.collectionObject.addRecord(this.classObject.record);
        this.dataChange('add')
        this.loading = false;
        this.modelDrawer.show = false
        return true
      } else {
        this.loading = false;
        return false
      }
    },
    async handleHierEditSubmit() {
      this.loading = true;
      let flag = await this.classObject.updateHierProperties()
      if (flag) {
        this.collectionObject.updateRecord(this.classObject.record)
        this.dataChange('edit')
        this.loading = false;
        this.modelDrawer.show = false
        this.registerDrawer.show = false
      } else {
        this.loading = false;
      }
    },
    async handleEditSubmit() {
      this.loading = true;
      let flag = await this.classObject.updateById()
      if (flag) {
        this.collectionObject.updateRecord(this.classObject.record)
        this.dataChange('edit')
        this.loading = false;
        this.modelDrawer.show = false
        this.registerDrawer.show = false
      } else {
        this.loading = false;
      }
    },
    handleCreate() {
      let defaultType = this.defaultType || this.type
      this.classObject.setRecord()
      this.defaultType && (this.classObject.record.type = defaultType)
      this.modelDrawer.status = 'new'
      this.modelDrawer.show = true
    },
    async handleEdit(row, index) {
      let filter = this.tableConfig.queryById ? {id: row.id} : { type: row.type, className: row.className }
      if (this.tableConfig.editBtnAction) {
        this[this.tableConfig.editBtnAction](row, index)
        return
      }
      this.loading = true;
      this.modelDrawer.status = 'edit'

      if (!this.modalNeedQuery) {
        this.classObject.setRecord(row)
        this.modelDrawer.show = true
        this.loading = false
      } else if (await this.getRecord(filter)) {
        this.modelDrawer.show = true
        this.loading = false;
      } else {
        this.loading = false;
      }
    },
    async handleDetail(row, index) {
      let filter = this.tableConfig.queryById ? {id: row.id} : { type: row.type, className: row.className }
      this.loading = true;
      this.modelDrawer.status = 'read'

      if (!this.modalNeedQuery) {
        this.classObject.setRecord(row)
        this.modelDrawer.show = true
        this.loading = false
      }
      else if (await this.getRecord(filter)) {
        this.modelDrawer.show = true
        this.loading = false;
      } else {
        this.loading = false;
      }
    },
    handleDelete(row, index) {
      console.log('handleDelete', this.deleteById);
      if (this.deleteById) {
        this.deleteRecordById([row.id])
      } else {
        this.deleteRecord([row.className])
      }
    },
    async handleDeleteMultiple(selection) {
      if (this.deleteById) {
        await this.deleteRecordById(selection.map(item => item.id))
      } else {
        await this.deleteRecord(selection.map(item => item.className))
      }
    },
    clearTableSelection(flag) {
      flag && (this.$refs.table.selection = [])
    },
    dataChange(type) {
      this.$emit('dataChange', type)
    },
  },
  created() {
    this.collectionObject = this.$modelObject.create(`${this.modelName}Collection`);
    
    this.classObject = this.$modelObject.create(this.modelName)
    this.modelFilter = util.getModelFilter.call(this, this.collectionObject)
  },
  beforeMount() {
    let filter = {}
    if (this.searchHistory) {
      filter = window.localStorage.getItem(`plat_${this.searchHistory}_searchObj`)
      filter = filter ? JSON.parse(filter) : {}
    }
    this.loadPage(this.pageNavigation, filter)
  },
  props:{
    title:{
      type:String
    },
    type:{
      type:String
    },
    prefix:{
      type:String
    },
    config: {
      default() {
        return {}
      }
    },
    computedConfig: {
      default() {
        return {}
      }
    },
    searchData: {
      default() {
        return {}
      }
    },
    isPointer: {
      type: Boolean
    },
    defaultType: {
      default: ''
    }
  },
  computed: {
    columns() {
      let res = [
        // {
        //   key: 'type',
        //   title: this.$t(`model.type`),
        //   minWidth: 100,
        //   align: 'center',
        //   show: true
        // },
        {
          key: 'className',
          title: this.$t(`model.className`),
          minWidth: 100,
          align: 'center',
          show: true
        },
        {
          key: 'comments',
          title: this.$t(`model.comments`),
          minWidth: 100,
          align: 'center',
          show: true
        },
        // {
        //   key: 'version',
        //   title: this.$t(`model.version`),
        //   minWidth: 50,
        //   align: 'center',
        //   show: true,
        // },
        // {
        //   key: 'published',
        //   title: this.$t(`model.published`),
        //   minWidth: 50,
        //   align: 'center',
        //   show: true
        // },
        {
          key: 'createTime',
          title: this.$t(`model.createTime`),
          minWidth: 112,
          align: 'center',
          show: true,
        },
        {
          key: 'updateTime',
          title: this.$t(`model.updateTime`),
          minWidth: 112,
          align: 'center',
          show: true,
        },
      ]
      return this.computedConfig.columns || res;
    },
    isNamedType(){
      return this.collectionObject.namedModelList && this.collectionObject.namedModelList.includes(this.type);
    },
    queryFormItem() {
      let res=[
        {
          key: 'className',
          title: {
            'zh-CN': '模型类名',
            'en-US': 'class name'
          }[this.G_Locale],
          config: {
            type: 'text',
            clearable: true,
          }
        },
        {
          key: 'comments',
          title: {
            'zh-CN': '备注',
            'en-US': 'comments'
          }[this.G_Locale],
          config: {
            type: 'text',
            clearable: true,
          }
        },
      ]
      if (!(this.prefix === 'routing' && !this.type)) {
        res.unshift(
          {
            key: 'type',
            title: {
              'zh-CN': '所属类型',
              'en-US': 'type'
            }[this.G_Locale],
            config: {
              type: 'select',
              options: this.typeList,
              clearable: true,
            }
        })
      }
      return res;
    },
    // 新增、查看、编辑弹窗，表单展示的字段
    modalFormItem() {
      let res = [
          {
              key: 'type',
              title: this.$t(`model.type`),
              config: {
                  type: 'text',
                  // options: this.typeList,
                  readonly: !!this.type,
                  // clearable: true,
              },
              editConfig: {
                  disabled: true
              },
              rules: [
                { required: true,
                  trigger: 'blur',
                  message: this.$t(`model.type`)+this.$t(`global.notEmpty`)
                },
                { trigger: 'blur',
                  validator: (rule, value, callback) => {
                    console.log("file: model.vue:404  modalFormItem  this.collectionObject.namedModelList:", this.collectionObject.namedModelList)
                    if (!this.type && this.collectionObject.namedModelList.includes(value)) {
                      return callback(new Error({ 'zh-CN': '不能使用这个类型', 'en-US': 'cannot use this type' }[this.G_Locale]));
                    }else {
                      callback();
                    }
                  }
                }
              ]
          },
          {
              key: 'className',
              title: this.$t(`model.className`),
              config: {
                  type: 'text',
                  maxlength: 50,
                  clearable: true,
                  placeholder:this.$t(`global.pleaseInput`) + this.$t(`model.className`),
              },
              editConfig: {
                  disabled: true
              },
              rules: [
                  { required: true, trigger: 'blur',message: this.$t(`model.className`)+this.$t(`global.notEmpty`)
                  }
              ]
          },
          {
              key: 'comments',
              title: this.$t(`model.comments`),
              span: 24,
              config: {
                  type: 'textarea',
                  autosize: {minRows: 1, maxRows: 5},
                  clearable: true,
                  placeholder: this.$t(`global.pleaseInput`) + this.$t(`model.comments`)
              }
          },
      ]
      return this.computedConfig.modalFormItem || res
    },
    collapseFormItem() {
      return this.queryFormItem
    },
    lang() {
      return {
        "en-US": {
          type: 'type',
          className: 'class name',
          instanceName: 'instance name',
          category: 'category',
          eventName: 'event name',
          comments: 'comments',
          version:'version',
          published:'published',
          createTime:'createTime',
          updateTime:'updateTime'
        },
        "zh-CN": {
          type: '所属类型',
          className: '模型类名',
          instanceName: '实例名',
          category: '分类',
          eventName: '事件名称',
          comments:'注释',
          version:'版本',
          published:'已发布',
          createTime:'创建时间',
          updateTime:'更新时间'
        },
      }[this.G_Locale]
    },
    typeList() {
        return this.$modelObject.getModelType(this.modelName.replace('Model', ''), this.type);
    },
    modalTitle() {
        let record = this.classObject.record
        return record ? `（${record.className}：${record.comments}）` : ''
    },
    additionalAction() {
      let buttons = []
      let action = this.tableConfig.additionalAction;

      if (!action || !action.show || !action.buttons || !action.buttons.length) {
        return { show: false }
      }

      action.buttons.forEach(item => {
        item.title = item.title[this.G_Locale]
        item.event = (row, index) => {
          let res = ''
          if (item.eventName && this[item.eventName]) {
            res = this[item.eventName](row, index)
          }
          if (item.triggerName) {
            res = this.$emit(item.triggerName, item, row, index)
          }
          return res;
        }
        buttons.push(item)
      })

      return {
        key: 'additionalAction',
        title: { 'zh-CN': '附加操作', 'en-US': 'addition action' }[this.G_Locale],
        slot: 'additionalAction',
        width: 280,
        fixed: 'right',
        align: 'center',
        ...action,
        buttons
      }
    },
    actionButtonsCalc() {
      let buttons = [];
      let actionButtons = this.tableConfig.actionButtons

      if (this.tableConfig.action && actionButtons && actionButtons.length) {
        actionButtons.forEach(item => {
          let newItem = {...item}
          newItem.title = item.title[this.G_Locale]
          newItem.event = (row, index) => {
            let res = ''
            if (item.eventName && this[item.eventName]) {
              res = this[item.eventName](row, index)
            }
            if (item.triggerName) {
              res = this.$emit(item.triggerName, item, row, index)
            }
            return res;
            // return item.eventName && this[item.eventName] ? this[item.eventName](row, index) : ''
          }
          buttons.push(newItem)
        })
      }
      return buttons
    }
  },
}
</script>
